package info.niwota.group;


import info.niwota.group.thread.Topic;
import info.niwota.group.thread.TopicListActivity;

import java.io.File;
import java.util.List;
import java.util.Random;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.Display;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.admob.android.ads.AdView;

public class EtalkActivity extends Activity implements Button.OnClickListener, Recorder.OnStateChangedListener, OnLongClickListener {

	private class SendTask extends AsyncTask<Void, Void, Integer> {
		private static final int WHAT_FAIL = 2;
		private static final int WHAT_OK = 1;

		private EtalkMessage msg;
		
		private Exception error;
		
		public SendTask(EtalkMessage msg) {
			this.msg = msg;
		}

		@Override
		protected Integer doInBackground(Void... params) {
			Integer rc;
			try {
				MailTemplate.send(EtalkActivity.this, msg);
				rc = (WHAT_OK);
			} catch (Exception e) {
				rc = (WHAT_FAIL);
				error = e;
			}
			return rc;
		}

		@Override
		protected void onCancelled() {
			try {
				dismissDialog(DIALOG_PROGRESS_SENDING);
			} catch (Exception e) {
			}
		}

		@Override
		protected void onPreExecute() {
			showDialog(DIALOG_PROGRESS_SENDING);
		}

		@Override
		protected void onPostExecute(Integer result) {
			try {
				dismissDialog(DIALOG_PROGRESS_SENDING);
			} catch (Exception e) {
			}
			if (result == null) {
				return;
			}
			switch (result) {
			case WHAT_OK: {
				toast(R.string.msg_send_ok, Toast.LENGTH_SHORT);
				doFinish();
				break;
			}
			case WHAT_FAIL: {
				// failed to send with smtp setting, attempt default services
				final String s = (error == null ? "" : error.getMessage());
				toast(R.string.msg_fail, s, Toast.LENGTH_LONG);
				break;
			}
			}
		}
	}
	private class SetBGTask extends AsyncTask<Void, Void, Void> {

		@Override
		protected Void doInBackground(Void... arg0) {
			return null;
		}

		private void load() {
			Context ctx = EtalkActivity.this;
			boolean showbg = Preferences.isShowBackground(ctx);
			long cid = contactId;
			if (!showbg) {
				setPhoto(cid);
				mLayout.setBackgroundResource(R.drawable.background_black);
				return;
			}
			//
			int sel = Preferences.getBackgroundSelection(ctx, Preferences.BG_SELECT_SAMPLE_ANDROID);
			boolean gonewild = false;
			if (sel == Preferences.BG_SELECT_GONE_WILD) {
				Random rand = new Random();
				//gone wild is the last selection
				sel = rand.nextInt(Preferences.BG_SELECT_GONE_WILD * 2); // make it 50 - 50 for image store vs others
				sel = (sel < Preferences.BG_SELECT_GONE_WILD ? sel : Preferences.BG_SELECT_PICK);
				gonewild = true;
			}
			switch(sel) {
			case Preferences.BG_SELECT_PHOTO: {
				try {
					mHeaderImage.setImageResource(R.drawable.icon);
					//
					Drawable bg = loadPhoto(cid, BackgroundImages.BG_SELECT_PHOTO_DEFAULT);
					mLayout.setBackgroundDrawable(bg);
				} catch (Exception e) {
					mLayout.setBackgroundResource(BackgroundImages.BG_SELECT_PHOTO_DEFAULT);
				}
				break;	
			}
			case Preferences.BG_SELECT_PICK: {
				try {
					setPhoto(cid);
					//
					String p = (gonewild ? BackgroundImages.getRandomImage(ctx) : Preferences.getBackgroundImagePath(ctx, null));
					if (p == null) {
						mLayout.setBackgroundResource(BackgroundImages.BG_SELECT_PICK_DEFAULT);
						return;
					}
					//
					Drawable bg = BackgroundImages.loadImage(ctx, new File(p));
					mLayout.setBackgroundDrawable(bg);
				} catch (Exception e) {
					mLayout.setBackgroundResource(BackgroundImages.BG_SELECT_PICK_DEFAULT);
				}
				break;
			}
			default:
				try {
					setPhoto(cid);
					//
					int resid = Preferences.getBackgroundSelectedResource(sel, BackgroundImages.BG_SELECT_DEFAULT);
					mLayout.setBackgroundResource(resid);
				} catch (Exception e) {
					mLayout.setBackgroundResource(BackgroundImages.BG_SELECT_DEFAULT);
				}
			}
		}

		@Override
		protected void onPostExecute(Void result) {
			try {
				load();
			} catch (Exception e) {
				//ignore
			}
		}
	}

	//private static final int DIALOG_NEW_ADDRESS = 2;
	private static final int DIALOG_PROGRESS_SENDING = 1;
	private static final int DIALOG_EDIT = 3;
	//private static final int DIALOG_EDITGREETING = 4;
	
	private static final int DIALOG_ATTACH = 5;
	private static final int DIALOG_HELP = 6;
	
	private static final int LISTNAME_MAX_LEN = 128;

	//private static final int MENU_ATTACH = R.id.etalk_attach_opt_menu_id;

	//private static final int MENU_ATTACHPHOTO = R.id.etalk_attachphoto_opt_menu_id;
	//private static final int MENU_ATTACHVIDEO = R.id.etalk_attachvideo_opt_menu_id;
	//private static final int MENU_EDITRECIPIENTS = R.id.etalk_recipients_opt_menu_id;
	//private static final int MENU_GREETING = R.id.etalk_greeting_opt_menu_id;
	//private static final int MENU_SETTING = R.id.etalk_setting_opt_menu_id;
	//private static final int MENU_EDITTO = R.id.etalk_edit_to_opt_menu_id;
	//private static final int MENU_EDITSUBJECT = R.id.etalk_edit_subject_opt_menu_id;
	//private static final int MENU_EDITBODY = R.id.etalk_edit_body_opt_menu_id;
	//private static final int MENU_SETUP = R.id.etalk_signature_opt_menu_id;
	
	private static final int RC_ATTACH = 10;
	private static final int RC_ATTACHPHOTO = RC_ATTACH + 2;
	private static final int RC_ATTACHVIDEO = RC_ATTACH + 1;
	//private static final int RC_EDITCONTACT = 6;
	//private static final int RC_EDITRECIPIENTS = 1;
	//private static final int RC_GREETING = 3;
	private static final int RC_SETTING = 2;
	private static final int RC_SETUP = 5;
	private static final int RC_VIEWATTACH = RC_ATTACH + 3;
	//private static final int RC_VOICEINPUT = 4;
	private static final int RC_TOPIC_LIST = 20;
	
	private static final String RECORDER_STATE_KEY = "recorder_state";
	private static final String SAMPLE_INTERRUPTED_KEY = "sample_interrupted";
	private static final String SAVED_ATTACH_KEY = "saved.attach.key";
	private static final String SAVED_ATTACHURI_KEY = "saved.attachuri.key";
	private static final String SAVED_BODY_KEY = "saved.body.key";
	private static final String SAVED_CONTACTID_KEY = "saved.contactid.key";
	//
	private static final String SAVED_NAME_KEY = "saved.name.key";
	private static final String SAVED_SUBJECT_KEY = "saved.subject.key";
	
	private static final String SAVED_TO_KEY = "saved.to.key";
	
	static final String TAG = "EtalkActivity";

	private static final int EDIT_INDEX_TO = 0;

	private static final int EDIT_INDEX_SUBJECT = 1;

	private static final int EDIT_INDEX_BODY = 2;



	//private MenuItem attachMenuItem;
	//private MenuItem attachPictureMenuItem;
	//
	//private MenuItem attachVideoMenuItem;

	private long contactId;
	
	private long current = System.currentTimeMillis();

	//private MenuItem editRecipientsMenuItem;
	//private MenuItem greetingMenuItem;
	
	private String listname;

	private Button mAcceptButton;
	private String mAttach;
	private TextView mAttachment;

	private String mAttachUri;
	private String mBody;

	private TextView mBodyText;
	private Button mDiscardButton;

	private String mErrorUiMessage = null; 

	private LinearLayout mExitButtons;

	private String mExtension = FileFormats.EXT_3GPP;
	//
	private final Handler mHandler = new Handler();

	private ImageView mHeaderImage;
	private LinearLayout mHeaderLayout;
	private TextView mHeaderSubject;
	private TextView mHeaderTo;

	private View mLayout;
	private long mMaxFileSize = Constants.AUDIO_FILE_MAX_SIZE;

	private ImageButton mPlayButton;

	private ImageButton mRecordButton;
	private ImageButton mRecordButton1;

	private View mRecordButtons;
	private Recorder mRecorder;
	private RemainingTimeCalculator mRemainingTimeCalculator;
	//
	private String mRequestedMimeType = FileFormats.AUDIO_3GPP;
	private boolean mSampleInterrupted = false;
	private BroadcastReceiver mSDCardMountEventReceiver = null;
	//
	private TextView mStateMessage1;
	private TextView mStateMessage2;
	private ProgressBar mStateProgressBar;
	private ImageButton mStopButton;
	private String mSubject;
	private String mTimerFormat;
	private TextView mTimerView;
	private String mTo;
	Runnable mUpdateTimer = new Runnable() {
		public void run() {
			updateTimerView();
		}
	};
	private VUMeter mVUMeter;
	private WakeLock mWakeLock;
	//private Dialog newAddressDialog;
	private boolean pendingAutoStart;
	//
	private SendTask pendingSendTask;
	
	private ProgressDialog sendProgressDialog;
	
	//private MenuItem settingMenuItem;

	private Dialog editDialog;

	private int editIndex;

	//private boolean greetingDirty;

	//private Dialog editGreetingDialog;

	//private MenuItem editMenuItem;

	//private MenuItem signatureMenuItem;

	//private Menu optionsMenu;

	private final boolean optionsEnabled = true;

	private Drawable drawable_send32;

	private Drawable drawable_save32;

	//private Button mSetupButton;

	private Uri addToMediaDB(File file, String name, String title) {
		Resources res = getResources();
		ContentValues cv = new ContentValues();
		//
		long modDate = file.lastModified();

		// Lets label the recorded audio file as NON-MUSIC so that the file
		// won't be displayed automatically, except for in the playlist.
		cv.put(MediaStore.Audio.Media.IS_MUSIC, "0");

		cv.put(MediaStore.Audio.Media.TITLE, title);
		cv.put(MediaStore.Audio.Media.DATA, file.getAbsolutePath());
		cv.put(MediaStore.Audio.Media.DATE_ADDED, (int) (current / 1000));
		cv.put(MediaStore.Audio.Media.DATE_MODIFIED, (int) (modDate / 1000));
		cv.put(MediaStore.Audio.Media.MIME_TYPE, mRequestedMimeType);
		cv.put(MediaStore.Audio.Media.ARTIST, res
				.getString(R.string.audio_db_artist_name));
		cv.put(MediaStore.Audio.Media.ALBUM, res
				.getString(R.string.audio_db_album_name));
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "Inserting audio record: " + cv.toString());
		}
		ContentResolver resolver = getContentResolver();
		Uri base = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "ContentURI: " + base);
		}
		Uri result = resolver.insert(base, cv);
		if (result == null) {
			new AlertDialog.Builder(this).setTitle(R.string.app_name)
					.setMessage(R.string.error_mediadb_new_record)
					.setPositiveButton(R.string.button_ok, null).setCancelable(
							false).show();
			return null;
		}
		//
		name = (TextUtils.isEmpty(name) ? res.getString(R.string.app_name)
				: name);
		//
		if (PlaylistUtils.getPlaylistId(this, name) == -1) {
			createPlaylist(res, resolver, name);
		}
		int audioId = Integer.valueOf(result.getLastPathSegment());
		addToPlaylist(resolver, audioId, PlaylistUtils.getPlaylistId(this, name));
		//
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "added playlist: " + name + " uri: " + result);
		}
		// Notify those applications such as Music listening to the
		// scanner events that a recorded audio file just created.
		sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, result));
		return result;
	}
	
	/*
	 * Add the given audioId to the playlist with the given playlistId; and
	 * maintain the play_order in the playlist.
	 */
	private void addToPlaylist(ContentResolver resolver, int audioId,
			long playlistId) {
		String[] cols = new String[] { "count(*)" };
		Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external",
				playlistId);
		Cursor cur = resolver.query(uri, cols, null, null, null);
		cur.moveToFirst();
		final int base = cur.getInt(0);
		cur.close();
		ContentValues values = new ContentValues();
		values.put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, Integer
				.valueOf(base + audioId));
		values.put(MediaStore.Audio.Playlists.Members.AUDIO_ID, audioId);
		resolver.insert(uri, values);
	}

	private void attempAutoRecord() {
		if (pendingAutoStart) {
			pendingAutoStart = false;
			// auto start recording
			doRecord();
		}
	}

	private void updateSubject(String subj) {
		//null clears subject
		mSubject = Utils.normalize(subj);
		mHeaderSubject.setText(mSubject);
	}

	private Dialog createEditDialog() {
		LayoutInflater lif = LayoutInflater.from(this);
        final View v = lif.inflate(R.layout.compose_text_edit, null);
        WindowManager wm  = (WindowManager)this.getSystemService(Context.WINDOW_SERVICE );
        Display di = wm.getDefaultDisplay();
        v.setMinimumHeight(di.getHeight());
        v.setMinimumWidth(di.getWidth());
        //
        int title = R.string.app_name; //placeholder for initial size alloc.
        AlertDialog.Builder b = new AlertDialog.Builder(this)
        	.setTitle(title)
            .setView(v)
            .setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                	//do we really need both var and view now as view is read only?
                	switch(editIndex) {
                	case EDIT_INDEX_TO:
                		final EditText te = (EditText) v.findViewById(R.id.compose_edit_recipient);
                		//parse and validate
                		String to = parseEmail(te.getText().toString());
                		updateRecipients(to, null);
                		break;
                	case EDIT_INDEX_SUBJECT:
                		final EditText se = (EditText) v.findViewById(R.id.compose_edit_title);
                		String s = se.getText().toString();
                		updateSubject(s);
                		//
                		//greetingDirty = true;
                		break;
                	case EDIT_INDEX_BODY:
                		final EditText be = (EditText) v.findViewById(R.id.compose_edit_body);
                		mBody = be.getText().toString();
                		mBodyText.setText(mBody);
                		//
                		//greetingDirty = true;
                		break;
                	default:
                	}	
                }
            })
            .setNegativeButton(R.string.button_cancel, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                }
            });
        Dialog d = b.create();
        //
        return d;
	}

	/**
	 * Parse and validate email addresses
	 * @param to
	 * @return
	 */
	private String parseEmail(String to) {
		if (!TextUtils.isEmpty(to)) {
			to = Utils.toString(Utils.parseEmail(to));
		}
		return to;
	}

//	private Dialog createNewAddressDialog() {
//		LayoutInflater li = LayoutInflater.from(this);
//		final View v = li.inflate(R.layout.contact_found, null);
//		final DialogInterface.OnClickListener l = new DialogInterface.OnClickListener() {
//				public void onClick(DialogInterface dialog, int which) {
////					try {
////						switch (which) {
////						case DialogInterface.BUTTON_POSITIVE:
////							addContact();
////							return;
////						case DialogInterface.BUTTON_NEUTRAL:
////							copyContact();
////							break;
////						default:
////							//skip
////						}
////					} catch (Exception e) {
////						toast(R.string.msg_fail,
////								e.getMessage(),
////								Toast.LENGTH_LONG);
////					}
////					//
////					attempAutoRecord();
//				}
//
////				private void copyContact() {
////					String to = mTo;
////					Utils.copyToClipboard(EtalkActivity.this, to);
////					String[] emails = Utils.toStringArray(to);
////					CharSequence text = getString(R.string.msg_copied, emails.length);
////					Toast.makeText(EtalkActivity.this, text, Toast.LENGTH_SHORT).show();
////				}
////
////				private void addContact() {
////					startRecipientsActivity();
////					finish(); //TODO continue with current activity?
////				}
//			};
//		AlertDialog.Builder b = new AlertDialog.Builder(this);
//		b.setView(v);
//		b.setTitle(R.string.dia_newaddress_found);
//		b.setPositiveButton(R.string.button_save, l);
//		b.setNeutralButton(R.string.button_copy, l);
//		b.setNegativeButton(R.string.button_skip, l);
//		return b.create();
//	}

	/*
	 * Create a playlist with the given default playlist name, if no such
	 * playlist exists.
	 */
	private Uri createPlaylist(Resources res, ContentResolver resolver,
			String email) {
		ContentValues cv = new ContentValues();
		cv.put(MediaStore.Audio.Playlists.NAME, res.getString(
				R.string.audio_db_playlist_name, email));
		Uri uri = resolver.insert(MediaStore.Audio.Playlists
				.getContentUri("external"), cv);
		if (uri == null) {
			new AlertDialog.Builder(this).setTitle(R.string.app_name)
					.setMessage(R.string.error_mediadb_new_record)
					.setPositiveButton(R.string.button_ok, null).setCancelable(
							false).show();
		}
		return uri;
	}

	private ProgressDialog createSendProgressDialog() {
		ProgressDialog pd = new ProgressDialog(this);
		pd.setMessage(getText(R.string.status_sending));
		pd.setIndeterminate(true);
		pd.setCancelable(false);
		return pd;
	}

	/*
	 * If we have just recorded a smaple, this adds it to the media data base
	 * and sets the result to the sample's URI.
	 */
	private void doAccept() {
		mRecorder.stop();
		//
		if (!hasContent()) {
			return;
		}
		//
		final String to = mHeaderTo.getText().toString();
		final String subj = mHeaderSubject.getText().toString();
		final String body = mBodyText.getText().toString();
		
		Uri uri = null;
		
		boolean canSave = (mRecorder.sampleDuration() > 0);
		if (canSave) {
			try {
				//
				String n = (TextUtils.isEmpty(listname) ? Utils.truncate(to,
						LISTNAME_MAX_LEN) : listname);
				uri = addToMediaDB(mRecorder.sampleFile(), n, subj);
				
			} catch (UnsupportedOperationException e) {
				// Database manipulation failure
				toast(R.string.msg_fail, e.getMessage(), Toast.LENGTH_LONG);
				return;
			}
			if (uri == null) {
				return; //back or continue?
			}
		}
		
//		String body = mBody;
		
//		Intent i = new Intent();
//		i.setData(uri);
//		i.putExtra(EtalkIntent.EXTRA_SUBJECT, subj);
//		i.putExtra(EtalkIntent.EXTRA_EMAIL, to);
//		i.putExtra(EtalkIntent.EXTRA_BODY, body);
//		i.putExtra(EtalkIntent.EXTRA_URI, mAttachUri);
//		//
//		setResult(RESULT_OK, i);
		
		//
		if (isSelf(to)) {
			if (canSave) {
				// only save recording to playlist
				toast(R.string.msg_saved, Toast.LENGTH_SHORT);
			}
			doFinish();
			//currently only save recording, not message/attachment
			//TODO save as draft?
			return;
		}
		
		// send via gmail
		
		try {
			Intent i = new Intent();
			i.setAction(Intent.ACTION_SEND);
			i.setType("message/rfc822");
			
			// email
			String[] tos = Utils.toStringArray(to);
			
			i.putExtra(Intent.EXTRA_EMAIL, tos);
			i.putExtra(Intent.EXTRA_SUBJECT, subj);
			i.putExtra(Intent.EXTRA_TEXT, body);
			
			if (uri != null) {
				i.putExtra(Intent.EXTRA_STREAM, uri);
			}
			
			//
			final PackageManager pm = getPackageManager();
			List<ResolveInfo> apps = pm.queryIntentActivities(i, 0);
		
			//("com.google.android.gm", "com.google.android.gm.ComposeActivity");
			
			for (ResolveInfo ri: apps) {
				ActivityInfo ai = ri.activityInfo;
				if (ai == null) {
					continue;
				}
				
				String pn = ai.packageName;
				
				if (Constants.DEBUG_ENABLED) {
					Log.d(TAG, "package name: " + pn);
				}
				
				if (pn != null && pn.contains("com.google.android.gm")) {
					Intent ni = new Intent(i);
					
		            ni.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT
		                    |Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
		            ni.setComponent(new ComponentName(ai.applicationInfo.packageName, ai.name));
					startActivity(ni);
					
					//
					doFinish();
					
					return;
				}
			}
			
		} catch (Exception e) {
			Toast.makeText(this, e.getMessage() + "", Toast.LENGTH_SHORT).show();
		}
		
		//String ti = getString(R.string.menu_composewith); 
		//startActivity(Intent.createChooser(i, ti));
		
//		String audio = (uri == null ? null : Utils.getDataPath(this, uri));
//		EtalkMessage msg = new EtalkMessage();
//		String id = (uri == null ? null : uri.getLastPathSegment());
//		msg.id = (id == null ? "-1" : id);
//		msg.name = listname;
//		msg.to = to;
//		msg.subject = subj;
//		msg.body = body;
//		msg.audio = audio;
//		msg.attach = mAttachUri;
//		//
//		SendTask task = new SendTask(msg);
//		boolean ac = (Preferences.isAccountConfigured(this));
//		if (ac) {
//			task.execute();
//		} else {
//			//only check once the very first time
//			final SharedPreferences pref = this.getSharedPreferences(
//					Preferences.ETALK, Activity.MODE_PRIVATE);
//			if (!pref.getBoolean(Preferences.SETUP_RUN, false)) {
//				pref.edit().putBoolean(Preferences.SETUP_RUN, true).commit();
//				//
//				pendingSendTask = task;
//				startSetupActivity(ac);
//				return;
//			} else {
//				//startSendActivity(msg);
//			}
//		}
	}

	private void doDiscard() {
		doClear();
		//
		toast(R.string.msg_discarded, Toast.LENGTH_SHORT);
	}

	private void doClear() {
		mRecorder.delete();
		//
		resetMessage();
	}

//	private void doEditContact() {
//		if (contactId < 0) {
//			return;
//		}
//		Intent i = new Intent(Intent.ACTION_EDIT);
//		//content://com.android.contacts/raw_contacts/1
//		Uri uri = ContactAdapter.buildContactUri(contactId);
//		i.setData(uri);
//		startActivityForResult(i, RC_EDITCONTACT);
//	}

	private void doFinish() {
		resetMessage();
		//
		boolean close = Preferences.isSendClose(this);
		if (close) {
			finish();
			return;
		}
	}

	private void doPlaylists() {
		Intent i = new Intent(this, PlaylistActivity.class);
		startActivity(i);
	}
	
//	private void doEditGreeting() {
//		if (greetingDirty) {
//			showDialog(DIALOG_EDITGREETING);
//		} else {
//			startGreetingActivity();
//		}
//	}

	private void doRecord() {
		mRemainingTimeCalculator.reset();
		if (!Environment.getExternalStorageState().equals(
				Environment.MEDIA_MOUNTED)) {
			mSampleInterrupted = true;
			mErrorUiMessage = getResources().getString(R.string.insert_sd_card);
			updateUi();
		} else if (!mRemainingTimeCalculator.diskSpaceAvailable()) {
			mSampleInterrupted = true;
			mErrorUiMessage = getResources()
					.getString(R.string.storage_is_full);
			updateUi();
		} else {
			stopAudioPlayback();
			//
			File sub = Files.getSubFolder(this, Files.SUB_AUDIO);
			int sampleRate = Preferences.getAudioSampleRate(this);
			int bitrate = FileFormats.BITRATE_5900;
			mRemainingTimeCalculator.setBitRate(bitrate);
			mRecorder.startRecording(sub, mRequestedMimeType, mExtension, sampleRate);
			//
			bitrate = mRecorder.getBitRate(); //adjust for actual
			mRemainingTimeCalculator.setBitRate(bitrate);
			if (mMaxFileSize != -1) {
				mRemainingTimeCalculator.setFileSizeLimit(mRecorder
						.sampleFile(), mMaxFileSize);
			}
		}
	}

	private void initContactId() {
		contactId = -1;
		
//		long cid = -1;
//		try {
//			Intent my = getIntent();
//			if (my != null) {
//				cid = my.getLongExtra(EtalkIntent.EXTRA_CONTACTID, -1);
//				//try name as well
//				if (cid == -1) {
//					String n = my.getStringExtra(EtalkIntent.EXTRA_NAME);
//					cid = findContactId(n);
//				}
//			}
//		} catch (Exception e) {
//			//e.printStackTrace();
//		}
//		contactId = cid;
	}
	
//	private long findContactId(String n) {
//		long cid = -1;
//		if (n != null) {
//			cid = ContactUtils.getId(this, n);
//		}
//		return cid;
//	}

	private boolean hasContent() {
		return (mRecorder != null && mRecorder.sampleDuration() > 0 || mAttach != null);
	}

	private boolean hasAttachment() {
		return (mAttach != null);
	}

	private boolean hasRecording() {
		return (mRecorder != null && mRecorder.sampleDuration() > 0);
	}

	private void initMessage() {
		//gather from intent
		Intent intent = getIntent();
		if (intent == null) {
			return; //restored instance?
		}
		Bundle extras = intent.getExtras();
		Uri uri = intent.getData();
		String act = intent.getAction();
		//
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "initMessage uri: " + uri);
			Log.d(TAG, "initMessage extras: " + extras);
			Log.d(TAG, "initMessage action: " + act);
		}
		//
		//figure out if any requested recipients
		//
		String to = null;
		//
		//check etalk extras first
		if (extras != null) {
			to = extras.getString(EtalkIntent.EXTRA_EMAIL);
			// dynamic list - from shortcut intent
			if (to == null) {
				String ln = extras.getString(EtalkIntent.EXTRA_NAME);
				if (ln != null) {
					String[] emails = ContactUtils.getEmail(this, ln);
					if (emails != null && emails.length > 0) {
						to = Utils.toString(emails);
					}
				}
			}
		}
		//SENDTO
		if (to == null) {
			// && ACTION_SENDTO/ ACTION_VIEW (browser)
			if (uri != null) {
				String s = uri.getScheme();
				if (Schemes.MAILTO.equals(s)) {
					to = uri.getSchemeSpecificPart();
				} else if (Schemes.IMTO.equals(s)) {
					to = uri.getLastPathSegment();
				} else if (Schemes.TALKTO.equals(s)) {
					to = uri.getSchemeSpecificPart();
				}
			}
		}
		//SEND
		if (to == null) {
			String[] tos = intent.getStringArrayExtra(Intent.EXTRA_EMAIL);
			if (tos != null) {
				to = Utils.toString(tos);
			}
		}
		//
		if (to != null) {
			// remove query
			int i = to.lastIndexOf("?");
			if (i > 0) {
				to = to.substring(0, i);
			}
		}
		mTo = to;
		//
		//Log.d(TAG, "to: " + mTo);
		//
		// get subject from:
		// 1. intent, 2. canned greeting 3. auto generated
		//
		String subj = null;
		if (extras != null) {
			subj = extras.getString(EtalkIntent.EXTRA_SUBJECT);
			if (TextUtils.isEmpty(subj)) {
				subj = extras.getString(Intent.EXTRA_SUBJECT);
			}
		}
		if (subj == null && uri != null) {
			String s = uri.getScheme();
			if ("mailto".equals(s)) {
				subj = Uri.parse("x:///" + uri.getSchemeSpecificPart())
						.getQueryParameter("subject");
			}
		}
		mSubject = subj;
		
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "subject: " + mSubject);
		}
		String body = null;
		body = intent.getStringExtra(EtalkIntent.EXTRA_BODY);
		if (body == null) {
			body = intent.getStringExtra(Intent.EXTRA_TEXT);
		}
		mBody = body;
		
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "body: " + mBody);
		}
		//
		mAttach = null;
		if (extras != null) {
			setAttach(extras);
		}
		if (mAttach == null && Intent.ACTION_SEND.equals(act)) {
			//web link/page
			try {
				String txt = intent.getStringExtra(Intent.EXTRA_TEXT);
				if (txt != null) {
					Uri u = Uri.parse(txt);
					if (u.getScheme().startsWith("http")) { //http or https
						mAttach = u.toString(); //display
						mAttachUri = mAttach; //
					}
				}
			} catch (Exception e) {
				//e.printStackTrace();
			}
			//image gallery etc
			try {
				Uri u = (Uri) extras.get(Intent.EXTRA_STREAM);
				if (u != null) {
					mAttachUri = Utils.getDataPath(this, u);
					File f = Files.toFile(mAttachUri);
					long len = f.length();
					mAttach = (len/1024) + "KB ";
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		//Log.d(TAG, "attach: " + mAttach + " mAttachUri: " + mAttachUri);
		//default and canned
		if (TextUtils.isEmpty(mSubject)) {
//			mSubject = Preferences.getGreetingSubject(this, null);
//			//
//			if (mSubject == null) {
//				Date date = new Date(current);
//				SimpleDateFormat sdf = new SimpleDateFormat(
//						getString(R.string.audio_db_title_format));
//				mSubject = getString(R.string.audio_db_title_name, sdf
//						.format(date));
//				mBody = "";
//			} else {
//				mBody = Preferences.getGreetingBody(this, "");
//			}
		}
	}

	/*
	 * Whenever the UI is re-created (due f.ex. to orientation change) we have
	 * to reinitialize references to the views.
	 */
	private void initResourceRefs() {
		//
		//admob
		boolean nolic = (License.isLicensed(this) == false);
		AdView banner = (AdView) findViewById(R.id.banner);
		banner.setEnabled(nolic);
		banner.setVisibility(nolic ? View.VISIBLE : View.GONE);
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "ads enabled? " + nolic);
		}
		//
		//
		try {
			drawable_send32 = new BitmapDrawable(BitmapFactory.decodeResource(this.getResources(), R.drawable.send32));
			drawable_save32 = new BitmapDrawable(BitmapFactory.decodeResource(this.getResources(), R.drawable.save32));
		} catch (Exception e) {
			e.printStackTrace();
		}
		//
		mLayout = findViewById(R.id.etalk_compose_layout);
		//
		mHeaderLayout = (LinearLayout) findViewById(R.id.headerLayout);
		mHeaderImage = (ImageView) findViewById(R.id.headerImage);
		mHeaderTo = (TextView) findViewById(R.id.headerTo);
		mHeaderSubject = (TextView) findViewById(R.id.headerSubject);
		mBodyText = (TextView) findViewById(R.id.bodyTextMessage);
		mAttachment = (TextView)findViewById(R.id.attachment);
		
		mAttachment.setVisibility(View.GONE);
		//
		mRecordButton = (ImageButton) findViewById(R.id.recordButton);
		mPlayButton = (ImageButton) findViewById(R.id.playButton);
		mStopButton = (ImageButton) findViewById(R.id.stopButton);

		mRecordButtons = findViewById(R.id.recordButtons);
		mRecordButton1 = (ImageButton) findViewById(R.id.recordButton1);

		mStateMessage1 = (TextView) findViewById(R.id.stateMessage1);
		mStateMessage2 = (TextView) findViewById(R.id.stateMessage2);
		mStateProgressBar = (ProgressBar) findViewById(R.id.stateProgressBar);
		mTimerView = (TextView) findViewById(R.id.timerView);

		mExitButtons = (LinearLayout) findViewById(R.id.exitButtons);
		//mSetupButton = (Button) findViewById(R.id.setupButton);
		mAcceptButton = (Button) findViewById(R.id.acceptButton);
		mDiscardButton = (Button) findViewById(R.id.discardButton);
		mVUMeter = (VUMeter) findViewById(R.id.uvMeter);
		//
		mTimerFormat = getString(R.string.timer_format);
		//
		mVUMeter.setRecorder(mRecorder);
		//
		addListeners();
	}

	private void addListeners() {
		//touch
		mRecordButton.setOnClickListener(this);
		mPlayButton.setOnClickListener(this);
		mStopButton.setOnClickListener(this);
		//mSetupButton.setOnClickListener(this);
		mAcceptButton.setOnClickListener(this);
		mDiscardButton.setOnClickListener(this);
		mRecordButton1.setOnClickListener(this);
		//
		//mAttachment.setOnClickListener(this);
		//
		mStateMessage1.setOnClickListener(this);
		//
		//mHeaderImage.setOnClickListener(this);
		//
		//mLayout.setOnLongClickListener(this);
		//mHeaderLayout.setOnClickListener(this);
		//mHeaderTo.setOnClickListener(this);
		//mHeaderSubject.setOnClickListener(this);
		//mBodyText.setOnClickListener(this);
		
		//long touch
		//mLayout.setOnLongClickListener(this); //settings
		//mHeaderLayout.setOnLongClickListener(this);
		//
		//mHeaderTo.setOnLongClickListener(this);
		//mHeaderSubject.setOnLongClickListener(this);
		//mBodyText.setOnLongClickListener(this);
	}

//	private boolean isMailToIntent() {
//		Intent i = getIntent();
//		if (i == null) {
//			return false;
//		}
//		if (Intent.ACTION_SENDTO.equals(i.getAction())) {
//			return true;
//		}
//		Uri u = i.getData();
//		if (u == null) {
//			return false;
//		}
//		String s = u.getScheme();
//		if (Schemes.MAILTO.equals(s) 
//				|| Schemes.IMTO.equals(s)
//				|| Schemes.TALKTO.equals(s)) {
//			return true;
//		}
//		return false;
//	}

	private Drawable loadPhoto(long id, int res) {
		Bitmap bm = ContactUtils.loadPhoto(this, id, res);
		return new BitmapDrawable(bm);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "onActivityResult requestCode: " + requestCode  + " resultCode: " + resultCode + " == "+ RESULT_OK +  " data: " + data);
		}
		//
		if (resultCode == RESULT_CANCELED && requestCode == RC_SETTING) {
			//setting changed by intent not notified
			updateSettingUi();
			//
			return;
		}
		if (resultCode == RESULT_OK) {
			switch (requestCode) {
//			case RC_EDITRECIPIENTS: {
//				String emails = null;
//				String list = null;
//				if (data != null) {
//					Bundle extras = data.getExtras();
//					if (extras != null) {
//						emails = extras.getString(EtalkIntent.EXTRA_EMAILS);
//						list = extras.getString(EtalkIntent.EXTRA_LISTNAME);
//						if (Constants.DEBUG_ENABLED) {
//							Log.d(TAG, "new list name: " + list);
//						}
//					}
//				}	
//				//
//				updateRecipients(emails, list);
//				break;
//			}
			case RC_SETTING: {
				updateSettingUi();
				break;
			}
//			case RC_GREETING: {
//				if (data != null) {
//					Bundle extras = data.getExtras();
//					if (extras != null) {
//						String subj = extras.getString(Greeting.EXTRA_TITLE);
//						updateSubject(subj);
//						//
//						String body = extras.getString(Greeting.EXTRA_BODY);
//						mBody = (body == null ? "" : body);
//						mBodyText.setText(mBody);
//						//
//						greetingDirty = false;
//					}
//				}
//				break;
//			}
			case RC_ATTACHPHOTO: {
				updateAttach(requestCode, data);
				break;
			}
			case RC_ATTACHVIDEO: {
				updateAttach(requestCode, data);
				break;
			}
			case RC_VIEWATTACH: {
				//
				break;
			}
			case RC_SETUP: {
				if (pendingSendTask != null) {
					if (Preferences.isAccountConfigured(this)) {
						pendingSendTask.execute();
					} else {
						//SendTask t = pendingSendTask;
						//startSendActivity(t.msg);
					}
					pendingSendTask = null;
				}
				updateButtonUi();
				break;
			}
			case RC_TOPIC_LIST:
			{
				updateHeader(data);
				break;
			}
//			case RC_EDITCONTACT: {
//				updateBackground();
//				break;
//			}
//			case RC_VOICEINPUT: {
//				handleVoiceInput(data);
//				break;
//			}
			default:
			}
		}
//		//auto record if skipped in onCreate
//		if (requestCode == RC_ATTACHPHOTO 
//				|| requestCode == RC_ATTACHVIDEO
//				|| requestCode == RC_EDITRECIPIENTS) {
//			attempAutoRecord();
//		}
	}

	private void updateHeader(Intent data) {
		if (data == null) {
			return;
		}
		Bundle extras = data.getExtras();
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "updateHeader data: " + data);
		}
		if (extras != null) {
			String subj = extras.getString(Topic.EXTRA_TITLE);
			updateSubject(subj);
			//
			String body = extras.getString(Topic.EXTRA_BODY);
			mBody = (body == null ? "" : body);
			mBodyText.setText(mBody);
			//
			String emails = extras.getString(Topic.EXTRA_EMAILS);
			String to = parseEmail(emails);
			String name = extras.getString(Topic.EXTRA_NAME);
    		updateRecipients(to, name);

			if (Constants.DEBUG_ENABLED) {
				Log.d(TAG, "name: " + name + " emails: " + emails
						+ " subject: " + subj + " body: " + body);
			}
		}
	}

	private void updateSettingUi() {
		updateAudioSettings();
		//
		mStateMessage1.setVisibility(View.VISIBLE);
		mStateMessage1.setText(mRequestedMimeType);
		//
		updateHeaderUi();
		updateButtonUi();
		
		setBackground();
	}

//	private void handleVoiceInput(Intent data) {
//		if (data == null) {
//			return; //ignore or treat as null input?
//		}
//		String vi = data.getStringExtra(EtalkIntent.EXTRA_INPUT);
//		switch(editIndex) {
//    	case EDIT_INDEX_TO:
//    		String to = parseEmail(vi);
//    		updateRecipients(to, null);
//    		break;
//    	case EDIT_INDEX_SUBJECT:
//    		updateSubject(vi);
//    		//
//    		greetingDirty = true;
//    		break;
//    	case EDIT_INDEX_BODY:
//    		mBody = (vi == null ? "" : vi);
//    		mBodyText.setText(mBody);
//    		//
//    		greetingDirty = true;
//    		break;
//    	default:
//    	}	
//	}

	private void updateRecipients(String emails, String list) {
		//null means self
		mTo = (isSelf(emails) ? "" : emails);
		mHeaderTo.setText(mTo);
		//
		listname = list;
		//
		updateButtonUi();
		//
		//contactId = findContactId(list);
		updateBackground(); //contact
		//
		mHeaderTo.requestFocus();
	}

	private void updateBackground() {
		Context ctx = this;
		int sel = Preferences.getBackgroundSelection(ctx, Preferences.BG_SELECT_SAMPLE_BLUESKEY);
		if (sel == Preferences.BG_SELECT_PHOTO)  {
			Drawable bg = loadPhoto(contactId, BackgroundImages.BG_SELECT_PHOTO_DEFAULT);
			mLayout.setBackgroundDrawable(bg);
		} else {
			setPhoto(contactId);
		}
	}

	/*
	 * Handle the buttons.
	 */
	public void onClick(View v) {
		//
		if (!v.isEnabled()) {
			return;
		}
		int id = v.getId();
		//
		switch (id) {
		case R.id.recordButton:
			doRecord();
			break;
		case R.id.playButton:
			mRecorder.startPlayback();
			break;
		case R.id.stopButton:
			mRecorder.stop();
			break;
//		case R.id.setupButton:
//			//doSetup();
//			break;
		case R.id.acceptButton:
			doAccept();
			break;
		case R.id.discardButton:
			doDiscard();
			break;
		case R.id.recordButton1: {
			//one button
			boolean rec = (mRecorder.state() == Recorder.IDLE_STATE && !hasRecording());
			if (rec) {
				doRecord();
			} else {
				doAccept();
			}
			break;
		}
		default:
			int s = mRecorder.state();
			boolean idle = (s == Recorder.IDLE_STATE);
			//only when idle
			if (idle) {
				switch(id) {
				case R.id.attachment:
					//doAttachment();
					break;
				case R.id.headerImage:
					//doGroup();
					break;
				case R.id.headerTo:
					//doEditMessage(EDIT_INDEX_TO);
					break;
				case R.id.headerSubject:
					//doEditMessage(EDIT_INDEX_SUBJECT);
					break;
				case R.id.bodyTextMessage:
					//doEditMessage(EDIT_INDEX_BODY);
					break;
				case R.id.stateMessage1:
					//won't allow until in future release 
					//we can convert the existing recording to required format
					if (!hasRecording()) {
						showPickFormatDialog();
					}
					break;
				}
			}
		}
	}

	private void doAttachment() {
		if (mAttachUri == null) {
			showDialog(DIALOG_ATTACH);
			
			//optionsMenu could be called before it is created
//			//this is a hack
//			if (optionsMenu == null) {
//				optionsEnabled = false;
//				openOptionsMenu();
//				optionsEnabled = true;
//			}
//			optionsMenu.performIdentifierAction(R.id.etalk_attach_opt_menu_id, 0);
		} else {
			startViewAttachmentActivity();
		}
	}
	
	private void doEditMessage(int id) {
		editIndex = id; //referenced later
		showDialog(DIALOG_EDIT);
//		boolean canSpeak = Utils.canSpeak(this);
//		if (canSpeak) {
//			doVoiceInput();
//		} else {
//			showDialog(DIALOG_EDIT);
//		}
	}
	
//	private void doVoiceInput() {
//		String h = null;
//		String s = null;
//		//
//		switch(editIndex) {
//		case EDIT_INDEX_TO:
//			h = getString(R.string.hint_recipient);
//			s = mTo;
//			break;
//		case EDIT_INDEX_SUBJECT:
//			h = getString(R.string.hint_subject);
//			s = mSubject;
//			break;
//		case EDIT_INDEX_BODY:
//			h = getString(R.string.hint_message);
//			s = mBody;
//			break;
//		default:
//		}
//		//
//		Intent i = new Intent(this, VoiceInputActivity.class);
//		i.putExtra(EtalkIntent.EXTRA_TITLE, h);
//		i.putExtra(EtalkIntent.EXTRA_INPUT, s);
//		startActivityForResult(i, RC_VOICEINPUT);
//	}

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "onConfigurationChanged" + newConfig);
		}
		super.onConfigurationChanged(newConfig);
		//
		// we're recreating UI, subject may be out of sync
		//syncUi();
		//
		setContentView(R.layout.etalk);
		initResourceRefs();
		//
		updateUi();
		setBackground();
	}

	@Override
	protected void onCreate(Bundle icycle) {
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "onCreate " + icycle);
		}
		super.onCreate(icycle);
		//
		Intent i = getIntent();
		if (i != null) {
			//
			boolean noop = i.getBooleanExtra(EtalkIntent.NOOP, false);
			if (noop) {
				String[] sa = i.getStringArrayExtra(Intent.EXTRA_EMAIL);
				String s = (sa == null || sa.length == 0 ? " " : sa[0]);
				//
				if (Constants.DEBUG_ENABLED) {
					Log.d(TAG, "onCreate: we started it first: " + i +" msg: " + s);
				}
				//this is the only app or user chose this
				toast(R.string.msg_fail, s, Toast.LENGTH_LONG);
				finish();
				return;
			}
			//
			listname = i.getStringExtra(EtalkIntent.EXTRA_NAME);
			if (Constants.DEBUG_ENABLED) {
				Log.d(TAG, "onCreate: list name: " + listname);
			}
		}
		//
		updateAudioSettings();
		//
		//requestWindowFeature(Window.FEATURE_LEFT_ICON);

		setTheme(android.R.style.Theme_Translucent_NoTitleBar);
		
		//
		requestWindowFeature(Window.FEATURE_NO_TITLE);

		//
		setContentView(R.layout.etalk);
		
		//setTitle(R.string.app_name);
		//getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
		//		R.drawable.etalk25);
		//
		mRecorder = new Recorder();
		mRecorder.setOnStateChangedListener(this);
		mRemainingTimeCalculator = new RemainingTimeCalculator();
		//
		PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
		mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK,
				"EtalkActivity");
		//
		initResourceRefs();
		//
		initMessage();
		//
		setResult(RESULT_CANCELED);
		registerExternalStorageListener();
		if (icycle != null) {
			restoreState(icycle);
		}
		
		updateUi();
		//
		initContactId();
		setBackground();
		//ok, ready to roll
		pendingAutoStart = (Preferences.isAutoStart(this));
		// from shortcut?
//		if (i != null) {
//			boolean sc = i.getBooleanExtra(EtalkIntent.EXTRA_SHORTCUT, false);
//			//Log.d(TAG, "shortcut: " + sc + " extras: " + i.getExtras());
//			if (sc) {
//				int mode = Preferences.getEtalkMode(this, 0);
//				switch(mode) {
//				case 1:
//					startAttachPhotoActivity();
//					return;
//				case 2:
//					startAttachVideoActivity();
//					return;
//				default:
//						//
//				}
//			}
//		}
		
//		// prompt for recipients if not set
//		//
//		if (isSelf(to)) {
//			startRecipientsActivity();
//			return;
//		}
		//
		//new address? prompt
		//only if launched as sendto/mailto
//		if (isMailToIntent()) {
//			String to = mHeaderTo.getText().toString();
//			if (Constants.DEBUG_ENABLED) {
//				Log.d(TAG, "checking new contact: " + to);
//			}
//			if (!TextUtils.isEmpty(to)) {
//				String[] emails = Utils.toStringArray(to);
//				//
//				for (String email: emails) {
//					if (email.indexOf("@") > 0 && 
//							!ContactUtils.hasEmail(this, email)) {
//						//got at least one new address
//						showDialog(DIALOG_NEW_ADDRESS);
//						return;
//					}
//				}
//			}
//		}
		//
		attempAutoRecord();
	}

	private void updateAudioSettings() {
		//no UI update here as this is also called in onCreate before resource is initialized.
		final String def = Preferences.getAudiotFormat(this);
		//to ensure backward compatibility and have a valid value as we removed support for audio/amr
		final String mime = (FileFormats.indexOf(this, def) == -1 ? FileFormats.AUDIO_3GPP : def);
		//
		mRequestedMimeType = mime;
		mExtension = FileFormats.extension(mime);
		//
		mMaxFileSize = Preferences.getAudioMax(this);
		//
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "updateAudioSettings mimetype: " + mRequestedMimeType + " ext: " + mExtension + " max: " + mMaxFileSize);
		}
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
//		case DIALOG_NEW_ADDRESS:
//			newAddressDialog = createNewAddressDialog();
//			return newAddressDialog;
		case DIALOG_PROGRESS_SENDING:
			sendProgressDialog = createSendProgressDialog();
			return sendProgressDialog;
		case DIALOG_EDIT:
			editDialog = createEditDialog();
			return editDialog;
//		case DIALOG_EDITGREETING:
//			editGreetingDialog = createEditGreetingDialog();
//			return editGreetingDialog;
		case DIALOG_ATTACH:
			return Dialogs.createAttachDialog(this);
		case DIALOG_HELP:
			return Dialogs.createHelpDialog(this);
		}
		return null;
	}

	private void showPickFormatDialog() {
		AlertDialog.Builder b = new AlertDialog.Builder(this);
        b.setTitle(R.string.compose_audio_format_title);
        final String[] fmts = getResources().getStringArray(R.array.compose_audio_format_values);
        final String def = Preferences.getAudiotFormat(this);
        int checked = 0;
        for (int i = 0; i < fmts.length; i++) {
        	if (fmts[i].equals(def)) {
        		checked = i;
        		break;
        	}
        }
        b.setSingleChoiceItems(R.array.compose_audio_format_entries, checked, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
            	String mime = fmts[which];
            	updateAudioFormat(mime);
            	dialog.dismiss();
            }
        });
        b.setNegativeButton(R.string.button_cancel, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
            	//
            }
        });
       Dialog d = b.create();
       //
       d.show();
	}

	private void updateAudioFormat(String mime) {
		mRequestedMimeType = mime;
    	mExtension = FileFormats.extension(mime);
    	mStateMessage1.setText(mime);
    	mStateMessage1.setVisibility(View.VISIBLE);
    	Preferences.putAudiotFormat(this, mime);
	}

//	private Dialog createEditGreetingDialog() {
//		return new AlertDialog.Builder(this).setCancelable(true).setTitle(
//				R.string.text_greeting_change_title).setMessage(
//				R.string.text_greeting_change_discard).setPositiveButton(
//				R.string.button_confirm, new DialogInterface.OnClickListener() {
//					public void onClick(DialogInterface arg0, int arg1) {
//						startGreetingActivity();
//					}
//				}).setNegativeButton(R.string.button_cancel, null).create();
//	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "onCreateOptionsMenu: " + menu);
		}
		
		MenuInflater mif = getMenuInflater();
		mif.inflate(R.menu.etalk_options, menu);
		
		//
		//optionsMenu = menu;
		//
		//editRecipientsMenuItem  = menu.findItem(R.id.etalk_recipients_opt_menu_id);
		//greetingMenuItem  = menu.findItem(R.id.etalk_greeting_opt_menu_id);
		//editMenuItem  = menu.findItem(R.id.etalk_edit_opt_menu_id);
		//signatureMenuItem  = menu.findItem(R.id.etalk_signature_opt_menu_id);
		//attachMenuItem  = menu.findItem(R.id.etalk_attach_opt_menu_id);
		//attachPictureMenuItem  = menu.findItem(R.id.etalk_attachphoto_opt_menu_id);
		//attachVideoMenuItem  = menu.findItem(R.id.etalk_attachvideo_opt_menu_id);
		//settingMenuItem  = menu.findItem(R.id.etalk_setting_opt_menu_id);
		//
		return true;
	}

	@Override
	public void onDestroy() {
		if (mSDCardMountEventReceiver != null) {
			unregisterReceiver(mSDCardMountEventReceiver);
			mSDCardMountEventReceiver = null;
		}
		super.onDestroy();
	}

	public void onError(int error) {
		Resources res = getResources();

		String message = null;
		switch (error) {
		case Recorder.SDCARD_ACCESS_ERROR:
			message = res.getString(R.string.error_sdcard_access);
			break;
		case Recorder.INTERNAL_ERROR:
			message = res.getString(R.string.error_app_internal);
			break;
		}
		if (message != null) {
			new AlertDialog.Builder(this).setTitle(R.string.app_name)
					.setMessage(message).setPositiveButton(R.string.button_ok,
							null).setCancelable(false).show();
		}
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			switch (mRecorder.state()) {
			case Recorder.IDLE_STATE:
				if (hasRecording()) {
					//reset recording
					mRecorder.clear();
				} else {
					setResult(RESULT_CANCELED);
					finish();
				}
				break;
			case Recorder.PLAYING_STATE:
				mRecorder.stop();
				break;
			case Recorder.RECORDING_STATE:
				//stop and clear
				mRecorder.clear();
				break;
			}
			return true;
		} else {
			return super.onKeyDown(keyCode, event);
		}
	}
	
	private void resetAll() {
		resetMessage();
		
		//clear headers
		mTo = null;
		mHeaderTo.setText(null);
		mSubject = null;
		mHeaderSubject.setText(null);
		mBody=null;
		mBodyText.setText(null);
	}

	private void resetMessage() {
		mAttachUri = null;
		mAttach = null;
		//
		mRemainingTimeCalculator.reset();
		mRecorder.clear();
	}

	private boolean hasHeader() {
		if (!TextUtils.isEmpty(mTo)) {
			return true;
		}
		if (!TextUtils.isEmpty(mSubject)) {
			return true;
		}
		if (!TextUtils.isEmpty(mBody)) {
			return true;
		}
		return false;
	}

	public boolean onLongClick(View v) {
		int id = v.getId();
		int s = mRecorder.state();
		boolean idle = (s == Recorder.IDLE_STATE);
		if (idle) {
			//long touch to edit recipients, greeting, or settings
			switch(id) {
//			case R.id.headerTo: 
//				doGroup();
//				return true;
//			case R.id.headerSubject:
//				doGroup();
//				return true;
//			case R.id.bodyTextMessage:
//				doGroup();
//				return true;
//			case R.id.headerLayout:
//				doGroup();
//				return true;
//			case R.id.etalk_compose_layout:
//				startSettingActivity();
//				return true;
			default:
			}
		}
		return false;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "onOptionsItemSelected: " + item);
		}
		int id = item.getItemId();
		switch (id) {
//		case MENU_EDITRECIPIENTS:
//			doEditRecipients();
//			return true;
//		case MENU_GREETING:
//			doEditGreeting();
//			return true;
//		case MENU_ATTACHPHOTO:
//			startAttachPhotoActivity();
//			return true;
//		case MENU_ATTACHVIDEO:
//			startAttachVideoActivity();
//			return true;
//		case MENU_ATTACH:
//			//
//			return true;
//		case MENU_EDITTO:
//			doEditMessage(EDIT_INDEX_TO);
//			return true;
//		case MENU_EDITSUBJECT:
//			doEditMessage(EDIT_INDEX_SUBJECT);
//			return true;
//		case MENU_EDITBODY:
//			doEditMessage(EDIT_INDEX_BODY);
//			return true;
		case R.id.etalk_setting_opt_menu_id:
			startSettingActivity();
			return true;
//		case R.id.etalk_signature_opt_menu_id:
//			doSetup();
//			return true;
//		case R.id.etalk_playlist_opt_menu_id:
//			doPlaylists();
//			return true;
//		case R.id.etalk_help_opt_menu_id:
//			doHelp();
//			return true;
//		case R.id.etalk_quit_opt_menu_id:
//			doQuit();
//			return true;
//		case R.id.etalk_group_opt_menu_id:
//			doGroup();
//			return true;
		}
		return false;
	}

	private void doGroup() {
		Intent i = new Intent(EtalkActivity.this, TopicListActivity.class);
		startActivityForResult(i, RC_TOPIC_LIST);
	}

	private void doQuit() {
		mRemainingTimeCalculator.reset();
		mRecorder.delete(); // updateUi is triggered by delete
		finish();
	}

	private void doHelp() {
		showDialog(DIALOG_HELP);
//		try {
//			Intent i = new Intent(this, WebBrowser.class);
//			i.setData( Uri.parse(HELP_URI));
//			startActivity(i);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
	}

	private void doSetup() {
		boolean ac = (Preferences.isAccountConfigured(this));
		startSetupActivity(ac);
	}

//	private void doEditRecipients() {
//		//
//		startRecipientsActivity();
//	}

	@Override
	protected void onResume() {
		super.onResume();
	}

	@Override
	protected void onPause() {
		mSampleInterrupted = (mRecorder.state() == Recorder.RECORDING_STATE);
		mRecorder.stop();
		//
		super.onPause();
	}

	@Override
	protected void onPrepareDialog(int id, Dialog v) {
		switch(id) {
//		case DIALOG_NEW_ADDRESS: {
//			try {
//				final TextView ee = (TextView) v.findViewById(R.id.contact_found_recipients);
//				String emails = mTo;
//				ee.setText(emails);
//			} catch (Exception e) {
//				//
//			}
//			break;
//		}
		case DIALOG_EDIT: {
	    	final EditText te = (EditText) v.findViewById(R.id.compose_edit_recipient);
        	final EditText se = (EditText) v.findViewById(R.id.compose_edit_title);
        	final EditText be = (EditText) v.findViewById(R.id.compose_edit_body);
        	//
        	switch(editIndex) {
        	case EDIT_INDEX_TO:
        		v.setTitle(R.string.hint_recipient);
        		te.setText(mTo);
        		te.setVisibility(View.VISIBLE);
        		se.setVisibility(View.GONE);
        		be.setVisibility(View.GONE);
        		break;
        	case EDIT_INDEX_SUBJECT:
        		v.setTitle(R.string.hint_subject);
        		te.setVisibility(View.GONE);
        		se.setText(mSubject);
        		se.setVisibility(View.VISIBLE);
        		be.setVisibility(View.GONE);
        		break;
        	case EDIT_INDEX_BODY:
        		v.setTitle(R.string.hint_message);
        		te.setVisibility(View.GONE);
        		se.setVisibility(View.GONE);
        		be.setText(mBody);
        		be.setVisibility(View.VISIBLE);
        		break;
        	default:
        	}
        	
			break;
		}
		default:
		}
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "onPrepareOptionsMenu: " + menu);
		}
		
		//disable options if not idle
//		int s = mRecorder.state();
//		boolean enable = (s == Recorder.IDLE_STATE);
		//
		//editRecipientsMenuItem.setEnabled(enable);
		//settingMenuItem.setEnabled(enable);
		//greetingMenuItem.setEnabled(enable);
		//editMenuItem.setEnabled(enable);
		//
		
//		boolean noac = (Preferences.isAccountConfigured(this) == false);
//		int st = (noac ? R.string.menu_setup : R.string.menu_signature);
//		signatureMenuItem.setEnabled(enable);
//		signatureMenuItem.setTitle(st);
		
		//show attach only if no existing attachment
		//boolean at = (enable && TextUtils.isEmpty(mAttach)); //
		//attachMenuItem.setEnabled(at);
		//attachVideoMenuItem.setEnabled(at);
		//attachPictureMenuItem.setEnabled(at);
		//
		return optionsEnabled;
	}

	@Override
	protected void onRestoreInstanceState(Bundle savedInstanceState) {
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "onRestoreInstanceState: " + savedInstanceState);
		}
		super.onRestoreInstanceState(savedInstanceState);
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "onSaveInstanceState: " + outState);
		}
		super.onSaveInstanceState(outState);
		//
		saveState(outState);
	}

	/*
	 * Called when Recorder changed it's state.
	 */
	public void onStateChanged(int state) {
		if (state == Recorder.PLAYING_STATE
				|| state == Recorder.RECORDING_STATE) {
			mSampleInterrupted = false;
			mErrorUiMessage = null;
		}

		if (state == Recorder.RECORDING_STATE) {
			mWakeLock.acquire(); // we don't want to go to sleep while recording
		} else {
			if (mWakeLock.isHeld()) {
				mWakeLock.release();
			}
		}
		updateUi();
	}

	@Override
	public void onStop() {
		//
		mRecorder.stop();
		super.onStop();
	}

	/*
	 * Registers an intent to listen for ACTION_MEDIA_EJECT/ACTION_MEDIA_MOUNTED
	 * notifications.
	 */
	private void registerExternalStorageListener() {
		if (mSDCardMountEventReceiver == null) {
			mSDCardMountEventReceiver = new BroadcastReceiver() {
				@Override
				public void onReceive(Context context, Intent intent) {
					String act = intent.getAction();
					if (Intent.ACTION_MEDIA_EJECT.equals(act)) {
						mRecorder.delete();
					} else if (Intent.ACTION_MEDIA_MOUNTED.equals(act)) {
						mSampleInterrupted = false;
						updateUi();
					}
				}
			};
			IntentFilter iFilter = new IntentFilter();
			iFilter.addAction(Intent.ACTION_MEDIA_EJECT);
			iFilter.addAction(Intent.ACTION_MEDIA_MOUNTED);
			iFilter.addDataScheme("file");
			registerReceiver(mSDCardMountEventReceiver, iFilter);
		}
	}

	private void restoreState(Bundle bundle) {
		try {
			contactId = bundle.getLong(SAVED_CONTACTID_KEY);
			listname = bundle.getString(SAVED_NAME_KEY);
			mTo = bundle.getString(SAVED_TO_KEY);
			mSubject = bundle.getString(SAVED_SUBJECT_KEY);
			mBody = bundle.getString(SAVED_BODY_KEY);
			mAttach = bundle.getString(SAVED_ATTACH_KEY);
			mAttachUri = bundle.getString(SAVED_ATTACHURI_KEY);
			//
			Bundle rec = bundle.getBundle(RECORDER_STATE_KEY);
			if (rec != null) {
				mRecorder.restoreState(rec);
				mSampleInterrupted = rec.getBoolean(
						SAMPLE_INTERRUPTED_KEY, false);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "restoreState: restored: listname: " + listname + " contactId: " + contactId);
		}
	}

	private void saveState(Bundle bundle) {
		try {
			String to = mHeaderTo.getText().toString();
			String subj = mHeaderSubject.getText().toString();
			//
			bundle.putString(SAVED_TO_KEY, to);
			bundle.putString(SAVED_SUBJECT_KEY, subj);
			bundle.putString(SAVED_BODY_KEY, mBody);
			bundle.putString(SAVED_ATTACH_KEY, mAttach);
			bundle.putString(SAVED_ATTACHURI_KEY, mAttachUri);
			bundle.putLong(SAVED_CONTACTID_KEY, contactId);
			bundle.putString(SAVED_NAME_KEY, listname);
			//
			if (mRecorder.sampleDuration() > 0) {
				Bundle rec = new Bundle();
				mRecorder.saveState(rec);
				rec.putBoolean(SAMPLE_INTERRUPTED_KEY, mSampleInterrupted);
				//
				bundle.putBundle(RECORDER_STATE_KEY, rec);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "saveState: saved: " + bundle);
		}
	}

	private void setAttach(Bundle extras) {
		mAttachUri = null;
		mAttach = null;
		if (extras == null) {
			return;
		}
		try {
			mAttachUri = extras.getString(EtalkIntent.EXTRA_URI);
			if (mAttachUri == null) {
				return;
			}
			File f = Files.toFile(mAttachUri);
			long len = f.length();
			mAttach = (len/1024) + "KB ";
			//
			if (Constants.DEBUG_ENABLED) {
				Log.d(TAG, "setAttach file: " + f.getPath());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void setBackground() {
		new SetBGTask().execute();
	}

	private void setPhoto(long cid) {
		Bitmap photo = ContactUtils.loadPhoto(this, cid, R.drawable.icon);
		mHeaderImage.setImageBitmap(photo);
	}

	private void showAttachment() {
		//attachment
		//mAttachment.setText(mAttach == null ? "" : mAttach);
		//mAttachment.setVisibility(mAttach == null ? View.GONE : View.VISIBLE);
		mAttachment.setVisibility(View.GONE);
	}

	void startAttachPhotoActivity() {
		String act = EtalkIntent.ACTION_PICTURE;
		Intent i = new Intent(this, AttachActivity.class);
		i.setAction(act);
		i.putExtra(EtalkIntent.EXTRA_NAME, listname);
		i.putExtra(EtalkIntent.EXTRA_EMAIL, mTo);
		startActivityForResult(i, RC_ATTACHPHOTO);
	}
	
	void startAttachVideoActivity() {
		String act = EtalkIntent.ACTION_VIDEO;
		Intent i = new Intent(this, AttachActivity.class);
		i.setAction(act);
		i.putExtra(EtalkIntent.EXTRA_NAME, listname);
		i.putExtra(EtalkIntent.EXTRA_EMAIL, mTo);
		startActivityForResult(i, RC_ATTACHVIDEO);
	}

//	private void startRecipientsActivity() {
//		Intent i = new Intent(this, RecipientsActivity.class);
//		String emails = mHeaderTo.getText().toString();
//		if (!isSelf(emails)) {
//			i.putExtra(EtalkIntent.EXTRA_EMAILS, emails);
//		}
//		i.putExtra(EtalkIntent.EXTRA_LISTNAME, listname);
//		startActivityForResult(i, RC_EDITRECIPIENTS);
//	}
//
//	private void startGreetingActivity() {
//		Intent i = new Intent(EtalkActivity.this, GreetingListActivity.class);
//		startActivityForResult(i, RC_GREETING);
//	}

//	private void startSendActivity(EtalkMessage msg) {
//		try {
//			MailTemplate.startSendActivity(this, msg);
//			doFinish();
//		} catch (ActivityNotFoundException e) {
//			toast(R.string.msg_noapp, e.getMessage(), Toast.LENGTH_LONG);
//		} catch (Exception e) {
//			toast(R.string.msg_fail, e.getMessage(), Toast.LENGTH_LONG);
//		}
//	}

	private void startSettingActivity() {
		Intent i = new Intent(this, EtalkSettingActivity.class);
		startActivityForResult(i, RC_SETTING);
	}

	private void startSetupActivity(boolean ac) {
		Intent i = new Intent(this, SetupActivity.class);
		int tab = (ac ? SetupActivity.TAB_SIGNATURE : SetupActivity.TAB_ACCOUNT);
		i.putExtra(SetupActivity.EXTRA_TAB, tab);
		startActivityForResult(i, RC_SETUP);
	}

	private void startViewAttachmentActivity() {
		if (mAttachUri == null) {
			return;
		}
		try {
			if (mAttachUri.startsWith("http")) {
				Uri uri = Uri.parse(mAttachUri);
				Intent i = new Intent(this, WebViewActivity.class);
				i.setData(uri);
				//
				//Log.d(TAG, "uri: "+uri);
				startActivityForResult(i, RC_VIEWATTACH);
			} else {
				Uri uri = Files.toUri(mAttachUri);
				String mimetype = Files.guessType(mAttachUri);
				Intent i = new Intent(Intent.ACTION_VIEW);
				i.setDataAndType(uri, mimetype);
				//
				//Log.d(TAG, "uri: "+uri+" mimetype: "+mimetype);
				//
				startActivityForResult(Intent.createChooser(i, ""), RC_VIEWATTACH);
			}
		} catch (Exception e) {
			Toast.makeText(this, getString(R.string.msg_fail, e.getMessage()),
					Toast.LENGTH_LONG).show();
		}
	}

	/*
	 * Make sure we're not recording music playing in the background, ask the
	 * MediaPlaybackService to pause playback.
	 */
	private void stopAudioPlayback() {
		// Shamelessly copied from MediaPlaybackService.java, which
		// should be public, but isn't.
		Intent i = new Intent("com.android.music.musicservicecommand");
		i.putExtra("command", "pause");

		sendBroadcast(i);
	}

//	/**
//	 * copy UI values back to instance variable which might have been changed via UI
//	 */
//	private void syncUi() {
//		//mTo no need
//		mSubject = mHeaderSubject.getText().toString();
//		mBody = mBodyTextMessage.getText().toString();
//		//
//		//Log.d(TAG, "***********************syncUi: "+" mSubject: " + mSubject + " mBody: " + mBody);
//	}

	private void toast(int resId, int duration) {
		Toast.makeText(this, resId, duration).show();
	}

	private void toast(int resId, String arg, int duration) {
		CharSequence text = getString(resId, arg);
		Toast.makeText(this, text, duration).show();
	}

	private void updateAttach(int requestCode, Intent data) {
		if (data != null) {
			Bundle extras = data.getExtras();
			setAttach(extras);
			//
			showAttachment();
			updateButtonUi();
		}
	}

	private void updateButtonUi() {
		boolean onebutton = Preferences.isOneButton(this);
		//
		int state = mRecorder.state();
		boolean hasRec = hasRecording();
		boolean self = isSelf(mTo);
		if (onebutton) {
			mRecordButtons.setVisibility(View.GONE);
			mRecordButton1.setVisibility(View.VISIBLE);
			//
			mRecordButton1.setFocusable(true);
			boolean rec = (state == Recorder.IDLE_STATE && hasRec == false);
			int icon = (rec ? R.drawable.record2 : (self ? R.drawable.save : R.drawable.send));
			mRecordButton1.setImageResource(icon);
			mExitButtons.setVisibility(View.INVISIBLE);
			mVUMeter.setVisibility(View.VISIBLE);
		} else {
			boolean hasCont = hasContent();
			//multi button
			mRecordButtons.setVisibility(View.VISIBLE);
			mRecordButton1.setVisibility(View.GONE);
			int recicon = (state == Recorder.IDLE_STATE ? R.drawable.record2 : R.drawable.record);
			mRecordButton.setImageResource(recicon);
			//exit buttons
			boolean exit = (hasCont && state != Recorder.RECORDING_STATE);
			mExitButtons.setVisibility(exit ? View.VISIBLE : View.INVISIBLE);
			mVUMeter.setVisibility(exit ? View.INVISIBLE : View.VISIBLE);
			//
			int txt = (self ? R.string.button_save : R.string.button_send );
			mAcceptButton.setText(txt);
			//
			if (drawable_send32 != null && drawable_save32 != null) {
				Drawable ico = (self ? drawable_save32 : drawable_send32);
				mAcceptButton.setCompoundDrawablesWithIntrinsicBounds(ico, null, null, null);
			}
			//enable only if audio exists or can send
			boolean accept = (self ? hasRec : hasCont);
			mAcceptButton.setEnabled(accept);
			//
			//boolean noac = (Preferences.isAccountConfigured(this) == false);
			//mSetupButton.setVisibility(noac ? View.VISIBLE : View.GONE);
		}
	}

	private void updateHeaderUi() {
		boolean b = Preferences.isShowHeaders(this);
		//Log.d(TAG, "updateHeaderUi: " + b);
		if (b) {
			boolean[] h = Preferences.getShowHeaders(this);
			mHeaderLayout.setVisibility(View.VISIBLE);

			//mHeaderToLabel.setVisibility(h[0] ? View.VISIBLE : View.GONE);
			mHeaderTo.setVisibility(h[0] ? View.VISIBLE : View.GONE);

			//mHeaderSubjectLabel.setVisibility(h[1] ? View.VISIBLE : View.GONE);
			int sb = (h[1] ? View.VISIBLE : View.GONE);
			mHeaderSubject.setVisibility(sb);
			int mb = (Preferences.isShowBody(this) ? View.VISIBLE : View.GONE);
			mBodyText.setVisibility(mb);
			
		} else {
			mHeaderLayout.setVisibility(View.GONE);
			mBodyText.setVisibility(View.GONE);
		}
		//
		// emails & subject
		mHeaderTo.setText(isSelf(mTo) ? "" : mTo);
		mHeaderSubject.setText(mSubject == null ? "" : mSubject);
		mBodyText.setText(mBody == null ? "" : mBody);
		//attachment
		showAttachment();
	}

	private static boolean isSelf(String s) {
		//
		return (s == null || s.equals("") || s.equals("<self>"));
	}

	/*
	 * Called when we're in recording state. Find out how much longer we can go
	 * on recording. If it's under 5 minutes, we display a count-down in the UI.
	 * If we've run out of time, stop the recording.
	 */
	private void updateTimeRemaining() {
		long t = mRemainingTimeCalculator.timeRemaining();
		if (t <= 0) {
			mSampleInterrupted = true;
			int limit = mRemainingTimeCalculator.currentLowerLimit();
			switch (limit) {
			case RemainingTimeCalculator.DISK_SPACE_LIMIT:
				mErrorUiMessage = getResources().getString(
						R.string.storage_is_full);
				break;
			case RemainingTimeCalculator.FILE_SIZE_LIMIT:
				mErrorUiMessage = getResources().getString(
						R.string.max_length_reached);
				break;
			default:
				mErrorUiMessage = null;
				break;
			}

			mRecorder.stop();
			return;
		}
		//
		Resources res = getResources();
		String ts = null;
		if (t < 60) {
			ts = String.format(res.getString(R.string.sec_available), t);
		} else if (t < 540) {
			ts = String.format(res.getString(R.string.min_available), (t / 60 + 1));
		}
		if (ts != null) {
			mStateMessage2.setText(ts);
		}
		long len = mRemainingTimeCalculator.currentSize();
		String sz = (len / 1024 + 1) + " KB";
		mStateMessage1.setText(sz);
	}

	/**
	 * Update the big MM:SS timer. If we are in playback, also update the
	 * progress bar.
	 */
	private void updateTimerView() {
		// Resources res = getResources();
		int state = mRecorder.state();

		boolean ongoing = (state == Recorder.RECORDING_STATE || state == Recorder.PLAYING_STATE);

		long time = ongoing ? mRecorder.progress() : mRecorder.sampleDuration();
		String timeStr = String.format(mTimerFormat, time / 60, time % 60);
		mTimerView.setText(timeStr);

		if (state == Recorder.PLAYING_STATE) {
			mStateProgressBar.setProgress((int) (100 * time / mRecorder
					.sampleDuration()));
		} else if (state == Recorder.RECORDING_STATE) {
			updateTimeRemaining();
		}

		if (ongoing) {
			mHandler.postDelayed(mUpdateTimer, 1000);
		}
	}

	/**
	 * Shows/hides the appropriate child views for the new state.
	 */
	private void updateUi() {
		Resources res = getResources();
		//
		switch (mRecorder.state()) {
		case Recorder.IDLE_STATE:
			boolean nocont = !hasContent();
			if (nocont) {
				mRecordButton.setEnabled(true);
				mRecordButton.setFocusable(true);
				mPlayButton.setEnabled(false);
				mPlayButton.setFocusable(false);
				mStopButton.setEnabled(false);
				mStopButton.setFocusable(false);
				mRecordButton.requestFocus();

				mStateMessage1.setVisibility(View.VISIBLE);
				mStateMessage1.setText(mRequestedMimeType);
				//
				mStateMessage2.setCompoundDrawablesWithIntrinsicBounds(R.drawable.idle_led, 0, 0, 0);
				//
				mStateMessage2.setVisibility(View.VISIBLE);
				mStateMessage2.setText(res.getString(R.string.record_your_message));

				mStateProgressBar.setVisibility(View.INVISIBLE);
			} else {
				mRecordButton.setEnabled(true);
				mRecordButton.setFocusable(true);
				mPlayButton.setEnabled(true);
				mPlayButton.setFocusable(true);
				mStopButton.setEnabled(false);
				mStopButton.setFocusable(false);

				//mStateMessage1.setVisibility(View.VISIBLE);
				mStateMessage1.setText(mRequestedMimeType);
				mStateMessage2.setVisibility(View.VISIBLE);
				
				if (hasRecording()) {
					mStateMessage2.setText(res.getString(R.string.message_recorded));
					mStateMessage2.setCompoundDrawablesWithIntrinsicBounds(R.drawable.recording_led, 0, 0, 0);
				} else {
					mStateMessage2.setText(res.getString(R.string.record_your_message));
					mStateMessage2.setCompoundDrawablesWithIntrinsicBounds(R.drawable.idle_led, 0, 0, 0);
				}

				mStateProgressBar.setVisibility(View.INVISIBLE);
			}

			if (mSampleInterrupted) {
				mStateMessage2.setVisibility(View.VISIBLE);
				mStateMessage2.setText(res
						.getString(R.string.recording_stopped));
				mStateMessage2.setCompoundDrawablesWithIntrinsicBounds(R.drawable.idle_led, 0, 0, 0);
			}

			if (mErrorUiMessage != null) {
				mStateMessage1.setText(mErrorUiMessage);
				//mStateMessage1.setVisibility(View.VISIBLE);
			}

			break;
		case Recorder.RECORDING_STATE:
			mRecordButton.setEnabled(false);
			mRecordButton.setFocusable(false);
			mPlayButton.setEnabled(false);
			mPlayButton.setFocusable(false);
			mStopButton.setEnabled(true);
			mStopButton.setFocusable(true);

			//mStateMessage1.setVisibility(View.VISIBLE);
			mStateMessage2.setCompoundDrawablesWithIntrinsicBounds(R.drawable.recording_led, 0, 0, 0);
			mStateMessage2.setVisibility(View.VISIBLE);
			mStateMessage2.setText(res.getString(R.string.recording));

			mStateProgressBar.setVisibility(View.INVISIBLE);
			break;

		case Recorder.PLAYING_STATE:
			mRecordButton.setEnabled(true);
			mRecordButton.setFocusable(true);
			mPlayButton.setEnabled(false);
			mPlayButton.setFocusable(false);
			mStopButton.setEnabled(true);
			mStopButton.setFocusable(true);

			//mStateMessage1.setVisibility(View.INVISIBLE);
			mStateMessage2.setVisibility(View.INVISIBLE);

			mStateProgressBar.setVisibility(View.VISIBLE);
			break;
		}
		//
		updateTimerView();
		mVUMeter.invalidate();
		//
		String s = null;
		if (mRecorder == null || mRecorder.mSampleDuration == 0
				|| mRecorder.mSampleFile == null) {
			s = mRequestedMimeType;
		} else {
			long len = mRecorder.mSampleFile.length();
			s = (len / 1024) + " KB";
			//mStateMessage1.setVisibility(View.VISIBLE);
		}
		mStateMessage1.setText(s);
		//
		updateHeaderUi();
		//
		updateButtonUi();
		//
	}	
}
